package com.etooling.pdm.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.etooling.framework.entity.Employee;
import com.etooling.framework.jpa.JpaQueryBuilder;
import com.etooling.framework.jpa.Specifications;
import com.etooling.framework.repository.AttachFileRepository;
import com.etooling.framework.svo.ReplyObj;
import com.etooling.framework.utils.WebUtils;
import com.etooling.pdm.entity.*;
import com.etooling.pdm.repository.*;
import com.etooling.pdm.service.GoodsService;
import com.etooling.pdm.vo.GoodsPropertiesValuesVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.*;

/**
 * @author dyz
 * @date 2023/4/4 13:43
 * @description GoodsServiceImpl
 */
@Service
public class GoodsServiceImpl implements GoodsService {
    @Autowired
    GoodsRepository goodsRepository;
    @Autowired
    GoodsPropValuesRepository goodsPropValuesRepository;
    @Autowired
    GoodsSpecsRepository goodsSpecsRepository;
    @Autowired
    GoodsPropRenameRulesRepository goodsPropRenameRulesRepository;
    @Autowired
    GoodsTypeRepository goodsTypeRepository;
    @Autowired
    AttachFileRepository attachFileRepository;
    @Autowired
    GoodsTypePropertiesRepository goodsTypePropertiesRepository;


    /**
     * @param request
     * @param goodsTypeId 分类id
     * @param vo          产品对象
     * @param pValuesJson json传递数据
     * @param goodsFileId 图片id
     * @return
     */
    @Transactional(rollbackFor = RuntimeException.class)
    @Override
    public ReplyObj create(HttpServletRequest request, String goodsTypeId, Goods vo, String pValuesJson, String goodsFileId) {
        try {
            String companyId = WebUtils.getSessionValue(request, WebUtils.LOGIN_COMPANY_ID_KEY);
            vo.setCompanyId(companyId);
            if (WebUtils.checkStr(goodsFileId)) {
                vo.setPhotoFile(attachFileRepository.getOne(goodsFileId));
            }

            Integer materialCodeCnt = goodsRepository.countMaterialCode(vo.getMaterialCode(), companyId, Goods.STATUS_IS_DEL);
            if (materialCodeCnt > 0) {
                return WebUtils.flushFailure(vo.getMaterialCode() + ",产品编码已经存在,无需重复录入");
            }
            //设置分类
            GoodsType goodsType = goodsTypeRepository.getById(goodsTypeId);
            vo.setGoodsType(goodsType);
            vo.setStatus(Goods.STATUS_IS_RUN);
            vo.setCreateTime(new Date());
            vo.setLastModifiedTime(new Date());
            Goods goods = goodsRepository.save(vo);

            Map<String, String> nameValues = new HashMap<>();
            List<GoodsPropertiesValuesVo> goodsPropValuesList = JSON.parseArray(pValuesJson, GoodsPropertiesValuesVo.class);
            for (GoodsPropertiesValuesVo gpVo : goodsPropValuesList) {
                //数据校验
                Integer cnt = goodsPropValuesRepository.getCountByCodeAndValue(gpVo.getId(), gpVo.getCode(), gpVo.getPValue());
                if (cnt > 0) {
                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                    return WebUtils.flushFailure(gpVo.getPropertiesName() + "出现校验异常(有同编码不同值的，有同值不同编码的)");
                }
                GoodsTypeProperties goodsTypeProperties = goodsTypePropertiesRepository.getById(gpVo.getId());
                GoodsPropValues gpv = new GoodsPropValues();
                gpv.setGoodsTypeProperties(goodsTypeProperties);
                gpv.setGoods(goods);
                gpv.setCode(gpVo.getCode());
                gpv.setpValue(gpVo.getPValue());
                goodsPropValuesRepository.save(gpv);
                nameValues.put(gpVo.getId(), gpVo.getPValue());
            }
            //按规则重命名
            List<GoodsPropRenameRules> goodsRenameRules = goodsPropRenameRulesRepository.getOutListByTypeId(goodsTypeId);
            if (goodsRenameRules.size() > 0) {
                StringBuilder goodsName = new StringBuilder();
//                String goodsCode = "";
                for (GoodsPropRenameRules rule : goodsRenameRules) {
                    String nameNode = "";
                    if (rule.getGoodsTypeProperties() != null) {
                        // 判断属性非空引用固定值
                        if (WebUtils.checkStr(rule.getFixedValue())) {
                            // 这个产品存在这个对应的属性
                            if (WebUtils.checkStr(nameValues.get(rule.getGoodsTypeProperties().getId()))) {
                                nameNode = rule.getFixedValue();
                            }
                        } else {
                            nameNode = nameValues.get(rule.getGoodsTypeProperties().getId());
                        }
                    } else {
                        if (WebUtils.checkStr(rule.getFixedValue())) {//判断属性非空引用固定值
                            nameNode = rule.getFixedValue();
                        }
                    }
                    goodsName.append(nameNode);
//                    if (WebUtils.checkStr(nameNode)) {
//                        goodsCode = goodsCode + StringtoEnUtils.getPinyinHeaderString(nameNode) + "-";
//                    }
                }
//                if (goodsCode.length() > 0) {
//                    goodsCode = goodsCode.substring(0, goodsCode.length() - 1);
//                }
//                goods.setMaterialCode(goodsCode);
                goods.setReqGoodsName(goodsName.toString());
                goodsRepository.save(goods);
            }
            return WebUtils.flushSuccess();
        } catch (Exception e) {
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return WebUtils.flushFailure();
        }
    }


    /**
     * 加法运算
     *
     * @param m1
     * @param m2
     * @return
     */
    public static double add(double m1, double m2) {
        BigDecimal p1 = new BigDecimal(Double.toString(m1));
        BigDecimal p2 = new BigDecimal(Double.toString(m2));
        return p1.add(p2).doubleValue();
    }


    @Override
    @Transactional(isolation = Isolation.SERIALIZABLE, rollbackFor = Exception.class)
    public ReplyObj addGoods(HttpServletRequest request, String json) {
        try {
            JSONObject jsonObject = JSON.parseObject(json);
            String goodsTypeId = jsonObject.getString("goodsTypeId");
            if (WebUtils.checkStr(goodsTypeId)) {
                String materialCode = jsonObject.getString("materialCode");
                GoodsType goodsType = goodsTypeRepository.getById(goodsTypeId);
                if (!WebUtils.checkStr(materialCode)) {
                    return WebUtils.flushFailure("没有唯一编码，无法添加");
                }
                String companyId = WebUtils.getSessionValue(request, WebUtils.LOGIN_COMPANY_ID_KEY);
                Integer count = goodsRepository.countMaterialCode(materialCode, companyId, Goods.STATUS_DELETE, goodsType.getIsProduct());
                if (count > 0) {
                    return WebUtils.flushFailure("唯一编码“" + materialCode + "”已经被占用了，无法添加此规格");
                }

                Goods goods = new Goods();
                goods.setCompanyId(companyId);

                goods.setGoodsType(goodsType);
                goods.setMaterialCode(materialCode);
                String name = jsonObject.getString("name");
                goods.setName(name);
                String reqGoodsName = jsonObject.getString("reqGoodsName");
                goods.setReqGoodsName(reqGoodsName);
                String unit = jsonObject.getString("unit");
                goods.setUnit(unit);
                String memo = jsonObject.getString("memo");
                goods.setMemo(memo);
                String imgId = jsonObject.getString("imgId");
                goods.setImgId(imgId);
                String imgUrl = jsonObject.getString("imgUrl");
                goods.setImgUrl(imgUrl);
                String goodsNamesPath = jsonObject.getString("goodsNamesPath");
                goods.setGoodsNamesPath(goodsNamesPath);
                String goodsCodesPath = jsonObject.getString("goodsCodesPath");
                goods.setGoodsCodesPath(goodsCodesPath);

                goods.setStatus(Goods.STATUS_IS_RUN);
                String loginId = WebUtils.getSessionValue(request, WebUtils.LOGIN_USER_KEY);
                Employee creator = new Employee();
                creator.setId(loginId);
                goods.setCreator(creator);
                Employee modifier = new Employee();
                modifier.setId(loginId);
                goods.setModifier(modifier);
                goods.setCreateTime(new Date());
                goods.setLastModifiedTime(new Date());

                goodsRepository.save(goods);

                JSONArray propList = jsonObject.getJSONArray("propList");
                List<GoodsPropValues> list = new ArrayList<>();
                for (int i = 0; i < propList.size(); i++) {
                    JSONObject prop = propList.getJSONObject(i);

                    String id = prop.getString("id");
                    String code = prop.getString("code");
                    String pValue = prop.getString("value");

                    GoodsPropValues goodsPropValues = new GoodsPropValues();
                    goodsPropValues.setGoodsType(goodsType);
                    goodsPropValues.setGoods(goods);
                    GoodsPropSetting goodsPropSetting = new GoodsPropSetting();
                    goodsPropSetting.setId(id);
                    goodsPropValues.setGoodsPropSetting(goodsPropSetting);
                    goodsPropValues.setCode(code);
                    goodsPropValues.setValue(pValue);
                    list.add(goodsPropValues);
                }
                goodsPropValuesRepository.saveAll(list);

                return WebUtils.flushSuccess();
            } else {
                return WebUtils.flushFailure("没有选择对应产品");
            }
        } catch (Exception e) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return WebUtils.flushFailure("添加型号时，数据不能成功解析");
        }
    }


    @Override
    @Transactional(isolation = Isolation.SERIALIZABLE, rollbackFor = Exception.class)
    public ReplyObj updateGoods(HttpServletRequest request, String json) {
        try {
            JSONObject jsonObject = JSON.parseObject(json);
            String id = jsonObject.getString("id");
            if (!WebUtils.checkStr(id)) {
                return WebUtils.flushFailure("找不到要修改的型号");
            }
            Goods goods = goodsRepository.getById(id);
            if (goods == null) {
                return WebUtils.flushFailure("找不到要修改的型号");
            }
            String materialCode = jsonObject.getString("materialCode");
            if (!WebUtils.checkStr(materialCode)) {
                return WebUtils.flushFailure("没有唯一编码，无法修改");
            }
            if (!materialCode.equals(goods.getMaterialCode())) {
                String companyId = WebUtils.getSessionValue(request, WebUtils.LOGIN_COMPANY_ID_KEY);
                Integer count = goodsRepository.countMaterialCode(materialCode, companyId, Goods.STATUS_DELETE, goods.getGoodsType().getIsProduct());
                if (count > 0) {
                    return WebUtils.flushFailure("唯一编码“" + materialCode + "”已经被占用了，无法添加此规格");
                }
                goods.setMaterialCode(materialCode);
            }
            String name = jsonObject.getString("name");
            goods.setName(name);
            String reqGoodsName = jsonObject.getString("reqGoodsName");
            goods.setReqGoodsName(reqGoodsName);
            String unit = jsonObject.getString("unit");
            goods.setUnit(unit);
            String memo = jsonObject.getString("memo");
            goods.setMemo(memo);
            String imgId = jsonObject.getString("imgId");
            goods.setImgId(imgId);
            String imgUrl = jsonObject.getString("imgUrl");
            goods.setImgUrl(imgUrl);
            String goodsNamesPath = jsonObject.getString("goodsNamesPath");
            goods.setGoodsNamesPath(goodsNamesPath);
            String goodsCodesPath = jsonObject.getString("goodsCodesPath");
            goods.setGoodsCodesPath(goodsCodesPath);

            goods.setStatus(GoodsSpecs.STATUS_RUNNING);
            String loginId = WebUtils.getSessionValue(request, WebUtils.LOGIN_USER_KEY);
            Employee modifier = new Employee();
            modifier.setId(loginId);
            goods.setModifier(modifier);
            goods.setLastModifiedTime(new Date());

            goodsRepository.save(goods);

            JpaQueryBuilder<GoodsPropValues> pb = Specifications.and();
            pb.eq("goods.id", id);
            List<GoodsPropValues> all = goodsPropValuesRepository.findAll(pb.build());
            goodsPropValuesRepository.deleteAll(all);

            JSONArray propList = jsonObject.getJSONArray("propList");
            List<GoodsPropValues> list = new ArrayList<>();
            for (int i = 0; i < propList.size(); i++) {
                JSONObject prop = propList.getJSONObject(i);

                String pid = prop.getString("id");
                String code = prop.getString("code");
                String pValue = prop.getString("value");

                GoodsPropValues goodsPropValues = new GoodsPropValues();
                goodsPropValues.setGoodsType(goods.getGoodsType());
                goodsPropValues.setGoods(goods);
                GoodsPropSetting goodsPropSetting = new GoodsPropSetting();
                goodsPropSetting.setId(pid);
                goodsPropValues.setGoodsPropSetting(goodsPropSetting);
                goodsPropValues.setCode(code);
                goodsPropValues.setValue(pValue);
                list.add(goodsPropValues);
            }
            goodsPropValuesRepository.saveAll(list);

            return WebUtils.flushSuccess();
        } catch (Exception e) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return WebUtils.flushFailure("添加规格时，数据不能成功解析");
        }
    }


    @Override
    @Transactional(isolation = Isolation.SERIALIZABLE, rollbackFor = Exception.class)
    public ReplyObj delGoods(HttpServletRequest request, String id) {
        try {
            delGoodsPropValues(id);
            goodsRepository.deleteById(id);
            return WebUtils.flushSuccess();
        } catch (Exception e) {
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            Goods goods = goodsRepository.getOne(id);
            goods.setStatus(Goods.STATUS_DELETE);
            goodsRepository.save(goods);
            return WebUtils.flushSuccess();
        }
    }


    /**
     * 删除规格属性配置的对应值
     *
     * @param goodsId 产品id
     */
    private void delGoodsPropValues(String goodsId) {
        JpaQueryBuilder<GoodsPropValues> pb = Specifications.and();
        pb.eq("goods.id", goodsId);
        List<GoodsPropValues> all = goodsPropValuesRepository.findAll(pb.build());
        goodsPropValuesRepository.deleteAll(all);
    }


}
